package distributedbank.requests;
import java.io.IOException;
import java.io.Serializable;

import distributedbank.responses.*;
import distributedbank.server.Account;
import distributedbank.server.BankBranch;
import distributedbank.Wrapper;

/**
 * A request to transfer a certain amount of cash from an account in the
 * current bank branch to an account at a different bank branch.
 */

public class TransferRequest extends GUIRequest {

    private int destBranchId;
    private int destAccountId;
    private int amount; // amount to transfer in cents

    /**
     * Note: the transactionId must be globally unique!
     */
    public TransferRequest(int branchId, int accountId, int transactionId,
                           int originatingClientId,
                           int destBranchId, int destAccountId, int amount) {
        super(branchId, accountId, transactionId, originatingClientId);
        this.destBranchId = destBranchId;
        this.destAccountId = destAccountId;
        this.amount = amount;
    }

    public void runRequest(BankBranch bankBranch, Wrapper wrapper) 
                throws IOException {
    	System.out.println(this.destBranchId + " " + this.branchId);
        if (this.destBranchId == this.branchId) {
            // don't use the network for internal transfers
            if (this.accountId == this.destAccountId) {
                // don't do a transfer if account and dest account are the
                // same
                System.out.println("Transfer of money between same account: "
                                   + this.accountId +
                                   " at branch " + this.branchId);
                Account acc = bankBranch.getAccount(this.accountId);
                int balance = acc.query(this.transactionId);
                Serializable message = new BalanceResponse(balance);
               	wrapper.sendMessage(message, this.branchId, this.originatingClientId);
            } else {
                // transfer between accounts at the same branch
                System.out.println("Transfering " + this.amount + " between "
                                   + this.accountId + " and "
                                   + this.destAccountId
                                   + " at branch " + this.branchId);
                Account acc = bankBranch.getAccount(this.accountId);
                Account acc2 = bankBranch.getAccount(this.destAccountId);
                int balance = acc.deposit(-this.amount, this.transactionId);
               	acc2.deposit(this.amount, this.transactionId);
               	Serializable message = new BalanceResponse(balance);
               	wrapper.sendMessage(message, this.branchId, this.originatingClientId);
            }
        } else {
            // use the network to transfer money
            System.out.println("Transfering " + this.amount +
                               " from account " + this.accountId +
                               " at branch " + this.branchId);
            Account acc = bankBranch.getAccount(this.accountId);
            Serializable depositMessage = new TransferDepositRequest(
            			this.branchId,
                        this.destBranchId, this.destAccountId,
                        this.transactionId, this.amount); 
            if(wrapper.sendMessage(depositMessage, this.branchId, this.destBranchId)){}
            else{
            	Serializable message = new ConnErrorResponse();
            	wrapper.sendMessage(message, this.branchId, this.originatingClientId);
            	return;
            }
            int balance = acc.deposit(-this.amount, this.transactionId);
            Serializable message = new BalanceResponse(balance);
            wrapper.sendMessage(message, this.branchId, this.originatingClientId);
        }
    }
}